#!/usr/bin/env ruby

# This script populates the library with shims within myExperiment workflows

env = "development"

unless ARGV[0].nil? or ARGV[0] == ''
  env = ARGV[0]
end

RAILS_ENV = env

# Load up the Rails app
require File.join(File.dirname(__FILE__), '..', 'config', 'environment')

require 'libxml'
require 'open-uri'
require File.join(File.dirname(__FILE__), '..', 'lib', 'tools.rb')

class PopulatorEngine
  def initialize
    @system_user = Tools.get_system_user
    Tools.create_default_categories
  end
  
  def populate
    @auto_populate_count = 0
    error_msg = ""
    begin
      queries = []
      print "\n\n\nCreating queries... "
      # CHANGE TO x.times { ... } WHERE x IS THE NUMBER OF PAGES FOR THE QUERIES
      1.times { |page_num|
        queries << URI.parse("http://www.myexperiment.org/search.xml?query=kind:(taverna%201)&type=workflow&page=#{page_num+1}")
      }
      1.times { |page_num|
        queries << URI.parse("http://www.myexperiment.org/search.xml?query=kind:(taverna%202)&type=workflow&page=#{page_num+1}")
      }
      print "Complete.\n\n"
      workflows = []
      
      print "Extracting workflow URIs...\n"
      queries.each do |query|        
        begin
          file_content = open(query).read
          
          query_xml = LibXML::XML::Parser.string(file_content).parse
          workflow_nodes = query_xml.find("/search/workflow")
          workflow_nodes.each do |node|
            print node.attributes["resource"], "\n"
            workflows << URI.parse("#{node.attributes["resource"]}/download") 
          end
        rescue
          error_msg += "Error processing query: " << query << "\n"
        ensure
          query_xml = nil
          file_content = nil
        end
      end
      print "Complete."
      
      print "\n\nExtracting shims from workflows...\n"
      # extract shims from each workflow
      workflows.each do |uri|
        begin
          print uri.to_s.gsub("/download", ""), ":  "
          file_content = open(uri).read
          parse_doc(file_content, uri.to_s.gsub("/download", ""))
        rescue
          error_msg += "Error processing workflow.\n"
        ensure
          file_content = nil
        end
      end
    rescue
      error_msg += "Error during library population.\n"
    ensure
      print error_msg, "\n\n*** Shims Extracted - #{@auto_populate_count} ***\n\n"
      return
    end
  end
  
  private
  
  def parse_doc(file_content, flow_uri=nil)
    error_msg = ""
    @shims_extracted = 0
    begin
      model = Tools.get_model(file_content)
      
      # get webservices and beanshells
      processor_collection = model.local_workers
      processor_collection << model.beanshells
      processor_collection.flatten!
      
      # add processors to shims library and store in shims collection
      # the indexes of shim_collection will match those of processor_collection
      # in the event that a shim could not be added to the library, a nil is 
      # entered into the corresponding index position 
      processor_collection.each do |processor|
        added = Tools.create_objects(@system_user, processor, model, flow_uri)        
        if added
          @shims_extracted+=1
          @auto_populate_count+=1
        end
      end
    rescue Exception => ex
      error_msg += ("\n" + ex.message) unless ex.message =~ /\s*/

#      puts "/* ************************************************************************* */"
#      puts "Exception: #{ex.class.name} - #{ex.message}"
#      puts ex.backtrace
#      puts "/* ************************************************************************* */"   
    ensure
      print error_msg, "Extracted => #{@shims_extracted}\n"
    end
  end
end



engine = PopulatorEngine.new
engine.populate
